package com.cloud.point.concurrent.general;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.LockSupport;

import lombok.extern.slf4j.Slf4j;

/**
 * 线程api使用
 *
 * @author 24373
 * @version 1.0
 * @date 2024-06-13 15:56
 */
@Slf4j
public class TestThreadApi {

    public static void main(String[] args) throws InterruptedException {

        //testJoin();
        //testInterrupt();
        testPark();

    }

    static int a = 10;

    /**
     * 线程的join方法
     *
     * @throws InterruptedException
     */
    private static void testJoin() throws InterruptedException {
        Thread t1 = new Thread(() -> {
            try {
                log.info("t1 :{}", a);
                a = 20;
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        });
        t1.start();
        /**
         * 等待t1执行完成
         * 1.没等够时间，直接返回
         * 2.等够时间，以线程实际结束时间为准
         */
        t1.join(2000);
        log.info("main :{}", a);
    }

    /**
     * interrupt 的使用
     * 1.可以判断 thread.isInterrupted() 的打断标记停止线程
     * 2.也可以判断全局打断标记变量停止线程
     */
    static volatile boolean flag = false;

    private static void testInterrupt() {
        Thread t1 = new Thread(() -> {
            while (true) {
                log.info("t1运行|<|>|{}", flag);
                Thread current = Thread.currentThread();
                //boolean interrupted = current.isInterrupted();

                // 判断是否被中断；停止线程
                if (flag) {
                    log.info("t1 is interrupted");
                    break;
                }
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    log.info("线程{}设置打断标记", current.getName());
                    /**
                     * sleep 线程被打断会 抛出异常 并且 清除打断标记
                     * - 需要重置打断标记；这时线程是运行状态，打断正常运行的线程, 不会清空打断状态
                     */
                    log.info("", e);
                    current.interrupt();
                }
            }
        });
        t1.start();

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        log.info("main interrupt t1..");
        // 可以提前打断阻塞的线程
        t1.interrupt();
        flag = true;

    }

    /**
     * park方法打断
     */
    private static void testPark() {
        Thread t1 = new Thread(() -> {
            for (int i = 0; i < 5; i++) {
                log.info("park..");
                LockSupport.park();
                log.info("park线程状态{}", Thread.currentThread().isInterrupted());
            }
        });
        t1.start();
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        // park 线程打断后不会清除打断标记
        t1.interrupt();

        //此方法可以判断打断状态并且清除打断标记
        //Thread.interrupted();

    }

}
